#!/bin/bash
##########批量下载指定目录hdfs文件########
#eg1:下载单个日期目录，下载20230407日期下目录
# sudo nohup     sh download.sh qingbo news toutiao.com  20230407 20230407  /data/lixinpeng/ &
# eg2:下载多个日期目录，下载20230407到20230501
#sudo nohup     sh download.sh qingbo news toutiao.com  20230407 20230501  /data/lixinpeng/ &
#####################################
#hadoop 目录
m_hadoop=/opt/hadoop-3.1.1.3.1.4.0-315/bin/hadoop
#hdfs 前缀,解压成功文件
pre_hdfs_path=/user/quantum_social/dataBackup/underlyingData/chengdu/das/product/download/success
#数据源/bool/20230111/ec/jd.com
#供应商 平台 数据源 日期  s_s_d 开始时间，s_e_d 结束时间
s_v=$1
s_p=$2
s_s=$3
s_d=$4
s_s_d=$4
s_e_d=$5
#下载本地目录
l_path=$6
#开始时间
startTime=$(date +%Y%m%d-%H:%M:%S)
startTime_s=$(date +%s)

check_dir() {
  #判断本地目录是否存在，不存在则创建
  base_dir=$l_path/$s_v-$s_p-$s_s/$currentDir/
  if [ ! -d $base_dir/"zip" ]; then
    mkdir -p $base_dir/"zip"
    mkdir -p $base_dir/"unzip"
    #需要下载文
    mkdir -p $base_dir/"files"
    echo "创建本地目录："$base_dir
  else
    echo "本地目录已经存在"
  fi
}
#下载
echo "下载开始"
cpFileUrlToLocalFile() {
  #保存待下载文件
  download_file=$base_dir/"files/"$s_v-$s_p-$s_s-$currentDir".txt"
  #需要下载源目录
  s_path=$pre_hdfs_path/$s_v/$currentDir/$s_p/$s_s/
  $($m_hadoop fs -ls $s_path/ | awk '{print $8}' >$download_file)
  #去掉第一行的空行
  sed -i '1d' $download_file
}
concurrentHandle() {
  #并发控制
  [ -e /tmp/fd1 ] || mkfifo /tmp/fd1 #创建有名管道
  exec 3<>/tmp/fd1                   #创建文件描述符，以可读（<）可写（>）的方式关联管道文件，这时候文件描述符3就有了有名管道文件的所有特性
  rm -rf /tmp/fd1                    #关联后的文件描述符拥有管道文件的所有特性,所以这时候管道文件可以删除，我们留下文件描述符来用就可以了
  for ((i = 1; i <= 2; i++)); do #线程数据3
    echo >&3 #&3代表引用文件描述符3，这条命令代表往管道里面放入了一个"令牌"
  done
}
downloadHandle() {
  #开始循环下载
  need_down_files=$(cat $download_file | wc -l)
  echo "需要下载文件："$need_down_files
  cat $download_file | while read line; do
    read -u3
    {
      echo "下载文件：$line"
      $($m_hadoop fs -get $line $base_dir"/zip/")
      fileName=${line##*/}
      echo "解压 $fileName"
      $(unzip -d $base_dir"/unzip" $base_dir"/zip"/$fileName) >/dev/null 2>&1
      echo >&3
    } &
  done
  wait
}

#存放日期数组
i=0
dateDirs=()
until [[ $day == "$s_e_d" ]]
do
        day=$(date -d "$s_s_d $i days" +%Y%m%d)
        dateDirs[${#dateDirs[*]}]=${day}
        ((i++))
done

#函数执行入库
#多个日期目录，逗号分隔
#dateDir=${s_d//,/ }
#dateDirs=$dateDir
#遍历数组
for currentDir in ${dateDirs[*]}; do
  echo "处理日期：$currentDir"
  check_dir currentDir
  cpFileUrlToLocalFile
  concurrentHandle
  downloadHandle
done

#执行结束时间
endTime=$(date +%Y%m%d-%H:%M:%S)
endTime_s=$(date +%s)
#执行总时间
sumTime=$(($endTime_s - $startTime_s))
echo "$startTime ---> $endTime" "Total:$sumTime seconds"